#pragma once

#include "RedefinableTemplateSignature.h"

#include "Classifier.h"
#include "RedefinableElement.h"
#include "TemplateParameter.h"

namespace uml {

RedefinableTemplateSignature::RedefinableTemplateSignature(const QString& umlType)
    : NamedElement(umlType) {}

void RedefinableTemplateSignature::fromJson(const QJsonObject& json, QStringList& errorList) {
    if (json.isEmpty()) {
        return;
    }

    NamedElement::fromJson(json, errorList);
    RedefinableElement::fromJson(json, errorList);
    TemplateSignature::fromJson(json, errorList);
    classifier_ = JsonSerializable::create<Classifier>(json.value("classifier"), errorList);

    JsonSerializable::fromJsonArray(extendedSignatures_, "extendedSignatures", json, errorList);
    JsonSerializable::fromJsonArray(inheritedParameters_, "inheritedParameters", json, errorList);
}

void RedefinableTemplateSignature::toJson(QJsonObject& json) {
    NamedElement::toJson(json);
    RedefinableElement::toJson(json);
    TemplateSignature::toJson(json);
    if (classifier_) {
        QJsonObject classifier_json;
        classifier_->toJson(classifier_json);
        json.insert("classifier", classifier_json);
    }
    JsonSerializable::toJsonArray(extendedSignatures_, "extendedSignatures", json);
    JsonSerializable::toJsonArray(inheritedParameters_, "inheritedParameters", json);
}

/// <summary>
/// isConsistentWith
    /// The query isConsistentWith() specifies, for any two
    /// RedefinableTemplateSignatures in a context in which redefinition is possible,
    /// whether redefinition would be logically consistent. A redefining template
    /// signature is always consistent with a redefined template signature, as
    /// redefinition only adds new formal parameters.
/// </summary>
    /// <code>
    /// result = (redefiningElement.oclIsKindOf(RedefinableTemplateSignature))
    /// </code>
    /// <code>
    /// redefiningElement.isRedefinitionContextValid(self)
    /// </code>
bool RedefinableTemplateSignature::isConsistentWith(shared_ptr<RedefinableElement> redefiningElement) const
{
    return false;
}

/// <summary>
/// classifier getter
/// The Classifier that owns this RedefinableTemplateSignature.
/// </summary>
shared_ptr<Classifier> RedefinableTemplateSignature::classifier() const {
    return classifier_;
}

/// <summary>
/// classifier setter
/// The Classifier that owns this RedefinableTemplateSignature.
/// </summary>
void RedefinableTemplateSignature::setClassifier(shared_ptr<Classifier> value) {
    classifier_ = value;
}

/// <summary>
/// extendedSignatures getter
/// The signatures extended by this RedefinableTemplateSignature.
/// </summary>
vector<shared_ptr<RedefinableTemplateSignature>>& RedefinableTemplateSignature::extendedSignatures() {
    return extendedSignatures_;
}

/// <summary>
/// inheritedParameters getter
/// The formal template parameters of the extended signatures.
/// </summary>
vector<shared_ptr<TemplateParameter>>& RedefinableTemplateSignature::inheritedParameters() {
    return inheritedParameters_;
}

} // namespace uml
